package com.example.administrator.solution.util;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

/**
 * AsyncTask的内部实现是一个线程池，所有提交的异步任务都会在这个线程池中的工作线程内执行，当工作线程需要跟UI线程交互时，
 * 工作线程会通过向在UI线程创建的Handler传递消息的方式，调用相关的回调函数，从而实现UI界面的更新。
 *
 * AsyncTask抽象出后台线程运行的五个状态，
 * 分别是：1、准备运行，2、正在后台运行，3、进度更新，4、完成后台任务，5、取消任务，对于这五个阶段，AsyncTask提供了五个回调函数：
 * 1、准备运行：onPreExecute(),该回调函数在任务被执行之后立即由UI线程调用。这个步骤通常用来建立任务，在用户接口（UI）上显示进度条
 * 2、正在后台运行：doInBackground(Params...),该回调函数由后台线程在onPreExecute()方法执行结束后立即调用。
 * 通常在这里执行耗时的后台计算。计算的结果必须由该函数返回，并被传递到onPostExecute()中。
 * 在该函数内也可以使用publishProgress(Progress...)来发布一个或多个进度单位。这些值将会在onProgressUpdate(Progress...)中被发布到UI线程。
 * 3.进度更新：onProgressUpdate(Progress...),该函数由UI线程在publishProgress(Progress...)方法调用完后被调用。一般用于动态地显示一个进度条。
 * 4. 完成后台任务：onPostExecute(Result),当后台计算结束后调用。后台计算的结果会被作为参数传递给这一函数。
 * 5、取消任务：onCancelled ()，在调用AsyncTask的cancel()方法时调用
 *
 *  AsyncTask的构造函数有三个模板参数：
 * 1.Params，传递给后台任务的参数类型。
 * 2.Progress，后台计算执行过程中，进步单位（progress　units）的类型。（就是后台程序已经执行了百分之几了。）
 * 3.Result，后台执行返回的结果的类型。 AsyncTask并不总是需要使用上面的全部3种类型。
 *
 * 标识不使用的类型很简单，只需要使用Void类型即可。
 *
 * @author fangzhibin
 *
 */

public class AsyncTaskUpdateView extends AsyncTask<Void, Integer, Void> {

    @SuppressLint("StaticFieldLeak")
    private ProgressBar mProgressBar;
    @SuppressLint("StaticFieldLeak")
    private Context mContext;
    @SuppressLint("StaticFieldLeak")
    private TextView mTextView;

    public AsyncTaskUpdateView(Context pContext, ProgressBar pProgressBar , TextView pTextView) {
        mContext = pContext;
        mProgressBar = pProgressBar;
        mTextView = pTextView;
    }

    /**
     * 在 doInBackground(Params...)之前被调用，在UI线程执行
     */
    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        mProgressBar.setProgress(0);
        mTextView.setText("0%");
    }

    /**
     * 处理后台执行的任务，在后台线程执行
     */
    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub

        // 将会调用onProgressUpdate(Integer... progress)方法

        int _Mac = mProgressBar.getMax();
        int _Current = mProgressBar.getProgress();

        while (_Current <= _Mac) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            publishProgress(_Current + _Mac / 10);
            _Current = _Current + _Mac / 10;
        }
        return null;
    }
    /**
     * 在调用publishProgress之后被调用，在UI线程执行
     */
    @SuppressLint("SetTextI18n")
    @Override
    protected void onProgressUpdate(Integer... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);
        mProgressBar.setProgress(values[0]);// 更新进度条的进度
        mTextView.setText(values[0]+"%");
    }
    /**
     * 后台任务执行完之后被调用，在UI线程执行
     */
    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        mProgressBar.setProgress(0);
        mTextView.setText("0%");
        Toast.makeText(mContext, "更新完毕", Toast.LENGTH_SHORT).show();
    }
}
